home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 22
/
Cream of the Crop 22.iso
/
doom
/
server_1.zip
/
_OBSERVE.QC
< prev
next >
Wrap
Text File
|
1996-10-04
|
16KB
|
495 lines
/*
**
** _observe.qc (Observer Code, 1.7)
**
** Copyright (C) 1996 Johannes Plass
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
** Author: Johannes Plass (plass@dipmza.physik.uni-mainz.de)
**
*/
//==============================================================
// Defaults
//==============================================================
// By default pressing 'jump' respawns a player, pressing fire
// changes to the next view. Setting OBSERVER_JUMP_RESPAWNS to 0
// in the next line inverts this behaviour.
float OBSERVER_JUMP_RESPAWNS = 1;
//==============================================================
// ObserverInfo
//==============================================================
void(entity player) ObserverInfo =
{
if (!USE_MODULE_OBSERVER) return;
// 123456789#123456789#123456789#12345678
sprint(player,"£");
sprint(player," Observer");
sprint(player, " allows you to peep.\n");
sprint(player," Type 'help-observer' for help.\n");
};
//==============================================================
// ObserverInit
//==============================================================
void(entity player) ObserverInit =
{
if (!USE_MODULE_OBSERVER) return;
stuffcmd(player,"alias help-observer \"impulse 205\";\n");
stuffcmd(player,"alias observer-noclip \"impulse 206\";\n");
};
//==============================================================
// ObserverActiveMessage
//==============================================================
void(entity player) ObserverActiveMessage =
{
if (!USE_MODULE_OBSERVER) return;
// 123456789#123456789#123456789#12345678
sprint(player," Observer (help-observer)\n");
};
//==============================================================
// ObserverHelp
//==============================================================
void(entity player) ObserverHelp =
{
if (!USE_MODULE_OBSERVER) return;
// 123456789#123456789#123456789#12345678
sprint(player,"Observer:");
sprint(player, " allows to watch the\n");
sprint(player,"ongoing madness.\n");
sprint(player,"As observer you can:\n");
sprint(player," - fly around.\n");
sprint(player," - move to another watch-spot by \n");
if (OBSERVER_JUMP_RESPAWNS)
sprint(player," pressing the fire-button. \n");
else
sprint(player," pressing the jump-button. \n");
sprint(player," - join the game as regular player\n");
if (OBSERVER_JUMP_RESPAWNS)
sprint(player," by pressing the jump-button. \n");
else
sprint(player," by pressing the fire-button. \n");
sprint(player,"Use the command 'observer-noclip' to\n");
sprint(player,"turn clipping on or off.\n");
if (OBSERVER_JUMP_RESPAWNS)
sprint(player,"Press the fire-button to become an\n");
else
sprint(player,"Press the jump-button to become an\n");
sprint(player,"observer when you are dead.\n");
};
//==============================================================
// ObserverThink
//==============================================================
void () ObserverThink =
{
//dprint("ObserverThink: executing\n");
if (!USE_MODULE_OBSERVER) return;
self.weaponmodel = "";
self.weaponframe = 0;
self.flags = self.flags | FL_ONGROUND;
{
local float invcos,nv,nvp,nvpmax,nvs,nsp,sp,svz;
local vector f,vp,vs;
svz = self.velocity_z * 0.75;
self.velocity_z = 0;
// v_forward is already normalized
f_x = v_forward_x;
f_y = v_forward_y;
f_z = 0;
invcos = vlen(f); if (invcos) invcos= 1/invcos; else invcos=0;
f = f*invcos; // normalize f
sp = f * self.velocity;
vp = sp*f;
nvp = vlen(vp); if (sp<0) nvp = nvp*(-1);
vs = self.velocity - vp;
vp = v_forward * (nvp * invcos);
vp_z = vp_z + svz;
nvp = vlen(vp);
nvpmax = (320 - 100*(v_forward * '0 0 1'));
if (nvp > nvpmax) { vp = vp * (nvpmax/nvp); }
self.velocity = vp + vs;
}
{
local entity e;
local float cont;
e = findradius(self.origin,75);
if (e) { cont = TRUE; }
else { cont = FALSE; }
while (cont) {
// dprint(e.classname); dprint("\n");
if (e.classname == "door") {
ObserverTeleportThroughDoor(self,e);
cont = FALSE;
}
if (e.classname == "trigger_teleport") {
ObserverTeleportThroughTeleporter(self,e);
cont = FALSE;
}
e = e.chain;
if (!e) { cont = FALSE; }
}
}
if (self.observer_status & OBSERVER_BECOME_OBSERVER) {
ObserverBecomeObserver(self);
return;
}
if (self.observer_status & OBSERVER_NEXTVIEW) {
self.observer_pos_num = self.observer_pos_num + 1;
ObserverSetPlayerPos(self);
self.observer_status = self.observer_status - OBSERVER_NEXTVIEW;
return;
}
if (self.observer_status & OBSERVER_TOGGLE_NOCLIP) {
if (self.movetype == MOVETYPE_FLY) {
self.movetype = MOVETYPE_NOCLIP;
sprint(self,"noclip on\n");
} else {
self.movetype = MOVETYPE_FLY;
sprint(self,"noclip off\n");
}
self.observer_status = self.observer_status - OBSERVER_TOGGLE_NOCLIP;
}
if (self.button0) {
self.observer_status = OBSERVER_BUTTON0;
return;
}
else if (self.button1) {
self.observer_status = 0;
return;
}
else if (self.button2) {
self.observer_status = OBSERVER_BUTTON2;
return;
}
if (OBSERVER_JUMP_RESPAWNS) {
if (self.observer_status & OBSERVER_BUTTON0) {
self.observer_status = OBSERVER_NEXTVIEW;
return;
}
if (self.observer_status & OBSERVER_BUTTON2) {
self.observer_status = OBSERVER_RESPAWN;
return;
}
} else {
if (self.observer_status & OBSERVER_BUTTON2) {
self.observer_status = OBSERVER_NEXTVIEW;
return;
}
if (self.observer_status & OBSERVER_BUTTON0) {
self.observer_status = OBSERVER_RESPAWN;
return;
}
}
if (self.observer_status & OBSERVER_RESPAWN) {
respawn();
// remove flag must be set after respawn()
PlayerStatusRemoveFlag(self,PLAYER_IS_OBSERVER);
return;
}
};
//==============================================================
// ObserverDeathThink
//==============================================================
float() ObserverDeathThink =
{
if (!USE_MODULE_OBSERVER) return(0);
if (self.button0) {
self.observer_status = OBSERVER_BUTTON0;
}
else if (self.button1) {
self.observer_status = 0;
}
else if (self.button2) {
self.observer_status = OBSERVER_BUTTON2;
}
else if (self.observer_status & (OBSERVER_BUTTON0 | OBSERVER_BUTTON2)) {
if (OBSERVER_JUMP_RESPAWNS) {
if (self.observer_status & OBSERVER_BUTTON0) self.observer_status = OBSERVER_BECOME_OBSERVER;
else self.observer_status = 0;
} else {
if (self.observer_status & OBSERVER_BUTTON2) self.observer_status = OBSERVER_BECOME_OBSERVER;
else self.observer_status = 0;
}
respawn();
}
self.button0 = 0;
self.button1 = 0;
self.button2 = 0;
return(1);
};
//==============================================================
// ObserverBecomeObserver
//==============================================================
void(entity player) ObserverBecomeObserver =
{
//dprint("ObserverBecomeObserver: executing\n");//#jp#(debug)
player.armorvalue = 0;
player.items = 0;
player.health = 999;
player.ammo_shells = 0;
player.ammo_nails = 0;
player.ammo_rockets = 0;
player.ammo_cells = 0;
player.weapon = 0;
player.currentammo = 1;
player.takedamage = DAMAGE_NO;
player.solid = SOLID_NOT;
player.movetype = MOVETYPE_FLY;
player.deadflag = DEAD_NO;
setmodel (player, string_null);
player.weaponmodel = "";
player.weaponframe = 0;
player.observer_pos_num = 0;
player.observer_status = 0;
player.observer_pos_num = 1 + random() * 4;
ObserverSetPlayerPos(player);
};
//==============================================================
// ObserverFindPos
//==============================================================
entity(entity player) ObserverFindPos =
{
local entity spot;
local float cont;
//dprint("ObserverFindPos: executing\n");
cont = 1;
while (cont<3) {
if (player.observer_pos_num <= 0) player.observer_pos_num = 1;
else if (player.observer_pos_num >= 21) player.observer_pos_num = 1;
if (player.observer_pos_num <= 5) {
spot = find (world, classname, "info_intermission");
if (player.observer_pos_num >= 2 && !(!spot)) spot = find (spot, classname, "info_intermission");
if (player.observer_pos_num >= 3 && !(!spot)) spot = find (spot, classname, "info_intermission");
if (player.observer_pos_num >= 4 && !(!spot)) spot = find (spot, classname, "info_intermission");
if (!spot) player.observer_pos_num = 5;
}
if (player.observer_pos_num >= 5) {
spot = find (world, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 6 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 7 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 8 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 9 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 10 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 11 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 12 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 13 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 14 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 15 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 16 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 17 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 18 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 19 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (player.observer_pos_num >= 20 && !(!spot)) spot = find (spot, classname, "info_player_deathmatch");
if (!spot) player.observer_pos_num = 21;
}
if (player.observer_pos_num >= 21) {
spot = find (world, classname, "info_player_start");
player.observer_pos_num = 21;
}
if (!spot) {
player.observer_pos_num = 0;
} else {
cont = 10;
}
cont = cont + 1;
}
if (!spot) error ("ObserverFindPos: could not find start pos");
return spot;
};
//==============================================================
// ObserverSetPlayerPos
//==============================================================
void(entity player) ObserverSetPlayerPos =
{
local entity pos;
//dprint("ObserverSetPlayerPos: executing\n");//#jp#(debug)
pos = ObserverFindPos(player);
player.angles = player.v_angle = pos.mangle;
player.fixangle = TRUE; // turn this way immediately
player.view_ofs = '0 0 12'; // must be != '0 0 0'
player.velocity = '0 0 0';
makevectors (player.angles);
setsize (player, '-12 -12 -12', '12 12 12');
// setsize (player, VEC_HULL_MIN, VEC_HULL_MAX);
// player.view_ofs = '0 0 22';
// avoid stuck observers for intermission spots
if (player.observer_pos_num <=4) setorigin (player, pos.origin + '0 0 -60');
else setorigin (player, pos.origin);
};
//==============================================================
// ObserverNoclip
//==============================================================
void(entity player) ObserverNoclip =
{
if (!USE_MODULE_OBSERVER) return;
player.observer_status = player.observer_status | OBSERVER_TOGGLE_NOCLIP;
};
//==============================================================
// ObserverTeleportThroughDoor
//==============================================================
void(entity player,entity door) ObserverTeleportThroughDoor =
{
local entity d,d_master;
local vector dmin,dmax;
d_master = d = door.owner;
if (d_master) {
dmin = d_master.absmin;
dmax = d_master.absmax;
} else {
dmin = dmax = '0 0 0';
}
if (dmin != dmax) {
// regular doors
if (d_master.state != STATE_BOTTOM) return;
do {
// dprint (vtos(d.absmin)); dprint (" "); dprint (vtos(d.absmax)); dprint ("\n");
if (d.absmin_x < dmin_x) { dmin_x = d.absmin_x; }
if (d.absmax_x > dmax_x) { dmax_x = d.absmax_x; }
if (d.absmin_y < dmin_y) { dmin_y = d.absmin_y; }
if (d.absmax_y > dmax_y) { dmax_y = d.absmax_y; }
if (d.absmin_z < dmin_z) { dmin_z = d.absmin_z; }
if (d.absmax_z > dmax_z) { dmax_z = d.absmax_z; }
d = d.enemy; // next linked door;
} while ((d != d_master) && (d != world));
}
else {
// secret doors
// we ignore these currently
return;
}
{
local float is_x,is_y,is_z,set;
local vector dir,or;
set = is_x = is_y = is_z = FALSE;
or = player.origin;
if (dmin_x + 15 < player.absmin_x && player.absmax_x < dmax_x - 15) is_x = TRUE;
if (dmin_y + 15 < player.absmin_y && player.absmax_y < dmax_y - 15) is_y = TRUE;
if (dmin_z + 15 < player.absmin_z && player.absmax_z < dmax_z - 15) is_z = TRUE;
// dprint("doors: "); dprint (vtos(dmin)); dprint (" "); dprint (vtos(dmax)); dprint ("\n");
// dprint("player: "); dprint (vtos(player.absmin)); dprint (" "); dprint (vtos(player.absmax)); dprint ("\n");
if (is_x && is_y) {
// dprint("door is in xy plane\n");
if (or_z < dmin_z) { dir = '0 0 1'; or_z = dmax_z + 25; }
else if (or_z > dmax_z) { dir = '0 0 -1'; or_z = dmin_z - 25; }
set = TRUE;
}
else if (is_x && is_z) {
// dprint("door is in xz plane\n");
if (or_y < dmin_y) { dir = '0 1 0'; or_y = dmax_y + 25; }
else if (or_y > dmax_y) { dir = '0 -1 0'; or_y = dmin_y - 25; }
set = TRUE;
}
else if (is_y && is_z) {
// dprint("door is in yz plane\n");
if (or_x < dmin_x) { dir = ' 1 0 0'; or_x = dmax_x + 25; }
else if (or_x > dmax_x) { dir = '-1 0 0'; or_x = dmin_x - 25; }
set = TRUE;
}
if (set) {
local vector v;
v = normalize(player.velocity);
if (dir * v < 0.5) return;
player.origin = or;
setorigin (player, player.origin);
}
}
};
//==============================================================
// ObserverTeleportThroughTeleporter
//==============================================================
void(entity player,entity tele) ObserverTeleportThroughTeleporter =
{
local entity targ;
local vector v1,v2;
v1 = ((tele.absmax + tele.absmin) * 0.5) - player.origin; normalize(v1);
v2 = player.velocity; normalize(v2);
if (v1 * v2 <= 0.1) return;
targ = find (world, targetname, tele.target);
if (!targ) {
dprint("ObserverTeleportThroughTeleporter: couldn't find teleporter target\n");
return;
}
makevectors (targ.mangle);
setorigin (player, targ.origin);
player.angles = targ.mangle;
player.fixangle = TRUE; // turn this way immediately
player.teleport_time = time + 0.7;
player.velocity = v_forward * 300;
// player.flags = player.flags - player.flags & FL_ONGROUND;
};